﻿using NetCore.Services;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;

namespace NetCore.Redis
{
    /// <summary>
    /// Redis基本信息初始化辅助类
    /// </summary>
    public class RedisManager
    {
        private static readonly object Locker = new object();
        private static ConnectionMultiplexer _instance = GetManager();
        private static ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>();

        /// <summary>
        /// Redis保存的Key前缀，会自动添加到指定的Key名称前
        /// </summary>
        internal static string RedisSysCustomKey = CustomConfigurationManager.Configuration["AppName"];

        /// <summary>
        /// 当前连接的Redis中连接字符串，格式为：127.0.0.1:6379,allowadmin=true,passowrd=pwd
        /// </summary>
        internal static string RedisHostConnection = CustomConfigurationManager.Configuration["Abp:RedisCache:ConnectionStrings"];
        /// <summary>
        /// 当前连接的Redis中的DataBase索引，默认0-16，可以在service.conf配置，最高64
        /// </summary>
        internal static int RedisDataBaseIndex = Convert.ToInt32(CustomConfigurationManager.Configuration["Abp:RedisCache:DatabaseId"]);

        ///// <summary>
        ///// netcore读取json配置文件接口
        ///// </summary>
        //private readonly IConfigurationRoot _appConfiguration;
        //public RedisManager(IConfigurationRoot appConfiguration)//IHostingEnvironment env,
        //{
        //    _appConfiguration = appConfiguration;//env.GetAppConfiguration();//
        //}

        /// <summary>
        /// 提供给上端初始化 上端可以读配置文件
        /// </summary>
        public static void Init()//IConfigurationRoot configuration//(Func<string, string> func)//
        {
            ////Func<string, string> func
            //RedisHostConnection = func.Invoke("Abp:RedisCache:ConnectionStrings");
            //RedisDataBaseIndex = Convert.ToInt32(func.Invoke("Abp:RedisCache:DatabaseId"));
            //RedisSysCustomKey = "NetCore";
            //RedisHostConnection = CustomConfigurationManager.Configuration["Abp:RedisCache:ConnectionStrings"];
            //RedisDataBaseIndex = Convert.ToInt32(CustomConfigurationManager.Configuration["Abp:RedisCache:DatabaseId"]);
        }

        static RedisManager()
        {
            RedisSysCustomKey = NetCoreConsts.AppName;//"NetCore";
            RedisHostConnection = CustomConfigurationManager.Configuration["Abp:RedisCache:ConnectionStrings"];
            RedisDataBaseIndex = Convert.ToInt32(CustomConfigurationManager.Configuration["Abp:RedisCache:DatabaseId"]);
        }

        /// <summary>
        /// 单例获取
        /// </summary>
        public static ConnectionMultiplexer Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (Locker)
                    {
                        if (_instance == null || !_instance.IsConnected)
                        {
                            _instance = GetManager();
                        }
                    }
                }
                return _instance;
            }
        }

        /// <summary>
        /// 缓存获取
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
        {
            if (!ConnectionCache.ContainsKey(connectionString))
            {
                ConnectionCache[connectionString] = GetManager(connectionString);
            }
            return ConnectionCache[connectionString];
        }

        /// <summary>
        /// 内部方法，获取Redis连接
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        private static ConnectionMultiplexer GetManager(string connectionString = null)
        {
            connectionString = connectionString ?? CustomConfigurationManager.Configuration["Abp:RedisCache:ConnectionStrings"];
            var connect = ConnectionMultiplexer.Connect(connectionString);
            return connect;
        }
    }
}
